﻿using System;
using System.Web;
using System.Web.Security;
using Web7.Core.Security.Users;

namespace Web7.Core.Security
{
    public class DefaultAuthenticationService : IAuthenticationService
    {
        public readonly Web7Context _httpContextAccessor;

        private readonly IAssistUserService<Guid> _userService;

        private IUser _signedInUser;

        public TimeSpan ExpirationTimeSpan { get; set; }

        public DefaultAuthenticationService(IAssistUserService<Guid> userService, Web7Context httpContextAccessor)
        {
            _userService = userService;
            ExpirationTimeSpan = TimeSpan.FromHours(6);
            _httpContextAccessor = httpContextAccessor;
        }

        public void SignIn(IUser user, bool createPersistentCookie)
        {
            var now = DateTime.UtcNow.ToLocalTime();
            var userData = Convert.ToString((user as Web7.Domain.Entity).Id);

            var ticket = new FormsAuthenticationTicket(
                1 /*version*/,
                user.UserName,
                now,
                now.Add(ExpirationTimeSpan),
                createPersistentCookie,
                userData,
                FormsAuthentication.FormsCookiePath);

            var encryptedTicket = FormsAuthentication.Encrypt(ticket);

            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
            cookie.HttpOnly = true;
            cookie.Secure = FormsAuthentication.RequireSSL;
            cookie.Path = FormsAuthentication.FormsCookiePath;
            if (FormsAuthentication.CookieDomain != null)
            {
                cookie.Domain = FormsAuthentication.CookieDomain;
            }

            _httpContextAccessor.User = user;
            var httpContext = _httpContextAccessor.HttpContext;
            httpContext.Response.Cookies.Add(cookie);
            _signedInUser = user;
        }

        public string GetSigInUrl()
        {
            return FormsAuthentication.LoginUrl;
        }

        public void SignOut()
        {
            _signedInUser = null;
            FormsAuthentication.SignOut();
        }

        public void SetAuthenticatedUserForRequest(IUser user)
        {
            _signedInUser = user;
        }

        public void Registration()
        {
            /*throw new NotImplementedException();*/
            ///TODO;
        }

        public IUser GetAuthenticatedUser()
        {
            if (_signedInUser != null)
                return _signedInUser;

            var httpContext = _httpContextAccessor.HttpContext;
            if (httpContext == null || !httpContext.Request.IsAuthenticated || !(httpContext.User.Identity is FormsIdentity))
            {
                return new UserAnonymous();
            }

            var formsIdentity = (FormsIdentity)httpContext.User.Identity;
            var userData = formsIdentity.Ticket.UserData;
            Guid userId;
            if (!Guid.TryParse(userData, out userId))
            {
                return new UserAnonymous();
            }

            return _userService.Get(userId);
        }

    }
}
